package boot.example.tcp.server.netty.config;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.handler.codec.base64.Base64Encoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * String 编码解码器, 出入站相对于服务端和客户端时相对的<br/>
 * 它是一个双向的handler，可以从channel中读取消息，也可以向channel中写入消息。
 * 继承 MessageToMessageCodec<ByteBuf, String> 时，可以加泛型 <br/>
 */
public class StringMessageCodec extends MessageToMessageCodec<Object, Object> {

// Netty也提供了MessageToMessageEncoder，将⼀种格式转化为另⼀种格式的编码器，也提供了⼀些 实现：
// 1 RedisEncoder 将Redis协议的对象进⾏编码
// 2 StringEncoder 将字符串进⾏编码操作
// 3 Base64Encoder 将Base64字符串进⾏编码操作


    /**
     * 编码
     *
     * @param ctx
     * @param msg
     * @param out
     * @throws Exception
     */
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("StringMessageCodec 消息正在进行编码...");

        // 直接生成序列化对象
        // 需要注意的是，使用protostuff序列化时，不需要知道pojo对象的具体类型也可以进行序列化时
        // 在反序列化时，只要提供序列化后的字节数组和原来pojo对象的类型即可完成反序列化
        String msg1 = msg.toString();
        out.add(Unpooled.copiedBuffer(msg1, CharsetUtil.UTF_8));//传递到下一个handler
    }

    /**
     * 解码
     *
     * @param ctx
     * @param msg
     * @param out
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("StringMessageCodec 正在进行消息解码...");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//传递到下一个handler
    }


}
